package com.bjut.vendormgrsys.web.rest;

import com.bjut.vendormgrsys.constant.Constant.UserStatus;
import com.bjut.vendormgrsys.service.CampaignService;
import com.bjut.vendormgrsys.service.MailService;
import com.bjut.vendormgrsys.service.UserService;
import com.bjut.vendormgrsys.support.bo.UserBO;
import com.bjut.vendormgrsys.util.DateUtils;
import com.bjut.vendormgrsys.util.PwdUtils;
import com.bjut.vendormgrsys.web.dto.user.*;
import com.bjut.vendormgrsys.web.dto.other.ResultRoleInfoList;
import com.bjut.vendormgrsys.web.dto.other.ResultRoleInfoListData;
import com.bjut.vendormgrsys.web.dto.ResultStatusList;
import com.bjut.vendormgrsys.web.dto.RoleInfo;
import com.bjut.vendormgrsys.web.dto.Status;
import com.bjut.vendormgrsys.web.dto.Success;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.media.Schema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

@RestController
public class UserApiController implements UserApi {

    private static final Logger log = LoggerFactory.getLogger(UserApiController.class);

    private final UserService userService;

    private final MailService mailService;

    private final BCryptPasswordEncoder encode;

    private final HttpServletRequest request;

    private final CampaignService campaignService;

    @Value("${login.url}")
    private String loginUrl;

    @org.springframework.beans.factory.annotation.Autowired
    public UserApiController(UserService userService, MailService mailService, BCryptPasswordEncoder encode, HttpServletRequest request,
                             CampaignService campaignService) {
        this.userService = userService;
        this.mailService = mailService;
        this.encode = encode;
        this.request = request;
        this.campaignService = campaignService;
    }

    public ResponseEntity<Success> userChangePasswordPost(@Parameter(in = ParameterIn.DEFAULT, schema = @Schema()) @Valid @RequestBody Body1 body) {
        ResponseEntity<Success> successEntity;
        try {
            log.info("encodePasswd:"+encode.encode(body.getNewPasswrod()));
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String presentedPassword = authentication.getCredentials().toString();
            String oldPassword = body.getOldPassword();
            if (!StringUtils.hasLength(oldPassword)) {
                throw new RuntimeException("旧密码不能为空！");
            }
            if (!presentedPassword.equals(oldPassword)) {
                throw new RuntimeException("旧密码不正确！");
            }
            String newPasswrod = body.getNewPasswrod();
            if (!StringUtils.hasLength(newPasswrod)) {
                throw new RuntimeException("新密码不能为空！");
            }
            UserBO creator = (UserBO) authentication.getPrincipal();
            String encodePasswd = encode.encode(newPasswrod);
            String tokenId = request.getHeader("Authorization");
            userService.changePassword(creator.getId(), tokenId, newPasswrod, encodePasswd);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.OK.value()).message("修改密码成功，请重新登陆！"), HttpStatus.OK);
        } catch (Exception e) {
            log.error("修改密码异常：", e);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("修改密码失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return successEntity;
    }

    @Override
    public ResponseEntity<Success> userAddScorePost(@Valid UserScoreInfo body) {
        ResponseEntity<Success> successEntity;
        try {
            campaignService.userAddScorePost(body);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.OK.value()).message("添加成功"), HttpStatus.OK);
        } catch (Exception e) {
            log.error("添加失败：", e);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("添加失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return successEntity;    }

    public ResponseEntity<Success> userChangeStatusPost(@Parameter(in = ParameterIn.DEFAULT, schema = @Schema()) @Valid @RequestBody List<Body> body) {
        ResponseEntity<Success> successEntity;
        try {
            userService.changeStatus(body);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.OK.value()).message("修改用户状态成功"), HttpStatus.OK);
        } catch (Exception e) {
            log.error("修改用户状态异常：", e);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("修改用户状态失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return successEntity;
    }

    public ResponseEntity<Success> userChangeAuditStatusPost(@Parameter(in = ParameterIn.DEFAULT, schema = @Schema()) @Valid @RequestBody List<Body> body) {
        ResponseEntity<Success> successEntity;
        try {
            userService.changeAuditStatus(body, loginUrl);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.OK.value()).message("修改用户审核状态成功"), HttpStatus.OK);
        } catch (Exception e) {
            log.error("修改用户审核状态异常：", e);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("修改用户审核状态失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return successEntity;
    }

    // TODO：新增修改分离？修改无权限限制，修改不涉及角色信息修改仅基本信息
    public ResponseEntity<Success> userCreatePost(@Parameter(in = ParameterIn.DEFAULT, required = true, schema = @Schema()) @Valid @RequestBody UserInfo body) {
        ResponseEntity<Success> successEntity;
        try {
            // TODO：校验用户名是否已存在，可单拆出来一个接口
            String account = body.getAccount();
            if(account == null){
                account = body.getEmail();
                body.setAccount(account);
            }
            UserInfo userInfo = userService.getUserInfoByAccount(account);
            String id = body.getId();
            boolean needEncode = true;
            String passwd = body.getPasswd();
            boolean isNew = false;
            if (!StringUtils.hasLength(id)) {
                // 新增用户
                if (userInfo != null) {
                    throw new Exception("用户名已存在：" + account);
                }
                passwd = PwdUtils.genRandomNum();
                body.setOriginPwd(passwd);
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                body.setStatus(UserStatus.ENABLE.getKey());
                UserBO creator = (UserBO) authentication.getPrincipal();
                body.setCreator(creator.getId());
                body.setDateCreated(DateUtils.now());
                body.setLastUpdated(null);
                isNew = true;
            } else {
                // 修改用户
                if (userInfo == null || !userInfo.getId().equals(id)) {
                    throw new Exception("用户不存在：" + account);
                }
                needEncode = !userInfo.getPasswd().equals(passwd);
                // 更新用户
                body.setLastUpdated(DateUtils.now());
            }
            if (needEncode) {
                String encodePasswd = encode.encode(passwd);
                body.setPasswd(encodePasswd);
            }
            userService.validUserInfo(body);
            userService.saveUserPO(body);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.OK.value()).message("保存用户成功"), HttpStatus.OK);
            if(isNew && body.getRole().equals("ROLE_HRBP")){
                mailService.send(body.getEmail(), body.getName(), body.getAccount(), passwd, loginUrl, "管理员");
            }
        } catch (Exception e) {
            log.error("保存用户异常：", e);
            successEntity = new ResponseEntity<>(new Success().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("保存用户失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return successEntity;
    }

    public ResponseEntity<ResultUserInfoList> userFindAllPost(@Parameter(in = ParameterIn.DEFAULT, schema = @Schema()) @Valid @RequestBody UserSearch body) {
        ResponseEntity<ResultUserInfoList> resultUserInfoListEntity;
        try {
            List<UserInfo> list = new ArrayList<>();
            long totalCount = userService.findAll(body, list);
            resultUserInfoListEntity = new ResponseEntity<>(new ResultUserInfoList().code(HttpStatus.OK.value()).message("成功").data(new ResultUserInfoListData().totalCount(totalCount).items(list)), HttpStatus.OK);
        } catch (Exception e) {
            log.error("获取用户列表异常：", e);
            resultUserInfoListEntity = new ResponseEntity<>(new ResultUserInfoList().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("获取用户列表失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return resultUserInfoListEntity;
    }

    public ResponseEntity<ResultRoleInfoList> userFindAllRoleGet() {
        ResponseEntity<ResultRoleInfoList> resultRoleInfoListEntity;
        try {
            List<RoleInfo> infoList = userService.findAllRole();
            resultRoleInfoListEntity = new ResponseEntity<>(new ResultRoleInfoList().code(HttpStatus.OK.value()).message("成功").data(new ResultRoleInfoListData().totalCount(infoList.size()).items(infoList)), HttpStatus.OK);
        } catch (Exception e) {
            log.error("获取角色列表异常：", e);
            resultRoleInfoListEntity = new ResponseEntity<>(new ResultRoleInfoList().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("获取角色列表失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return resultRoleInfoListEntity;
    }

    public ResponseEntity<ResultStatusList> userStatusListGet(String role) {
        ResponseEntity<ResultStatusList> responseEntity;
        try {
            List<Status> data = userService.findAllStatus(role);
            responseEntity = new ResponseEntity<>(new ResultStatusList().code(HttpStatus.OK.value()).message("成功").data(data), HttpStatus.OK);
        } catch (Exception e) {
            log.error("查询用户状态列表异常：", e);
            responseEntity = new ResponseEntity<>(new ResultStatusList().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("查询用户状态列表失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return responseEntity;
    }

    public ResponseEntity<ResultUserInfo> userUserInfoGet() {
        ResponseEntity<ResultUserInfo> entity;
        try {

            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            UserInfo data = userService.getUserInfoByUserBO((UserBO) authentication.getPrincipal());
            entity = new ResponseEntity<>(new ResultUserInfo().code(HttpStatus.OK.value()).message("成功").data(data), HttpStatus.OK);
        } catch (Exception e) {
            log.error("获取用户信息异常：", e);
            entity = new ResponseEntity<>(new ResultUserInfo().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("获取用户信息失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return entity;
    }

    public ResponseEntity<ResultUserInfo> userUserInfoByIdGet(String id) {
        ResponseEntity<ResultUserInfo> entity;
        try {
            UserInfo data = userService.getUserInfoById(id);
            entity = new ResponseEntity<>(new ResultUserInfo().code(HttpStatus.OK.value()).message("成功").data(data), HttpStatus.OK);
        } catch (Exception e) {
            log.error("获取用户信息异常：", e);
            entity = new ResponseEntity<>(new ResultUserInfo().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).message("获取用户信息失败：" + e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return entity;
    }
}
